package cn.changeforyou.generator.db.mybatisPlus;

import cn.changeforyou.generator.core.Generator;
import cn.changeforyou.generator.core.GeneratorContext;
import cn.changeforyou.generator.terminal.TerminalApplication;
import cn.changeforyou.generator.terminal.TerminalModel;

import java.io.*;
import java.util.ArrayList;
import java.util.List;

/**
 * @author zhyu
 * @date 2021/1/30 14:42
 */
public class ServiceGenerator implements Generator, TerminalApplication {


	public static final String PROJECT_PATH = "projectPath";
	public static final String ENTITY_NAME = "entityName";
	public static final String SERVICE_PATH = "servicePath";

	@Override
	public void init() {

	}

	public static void main(String[] args) {
		ServiceGenerator serviceGenerator = new ServiceGenerator();
		GeneratorContext context = new GeneratorContext();
		context.setValue(PROJECT_PATH, "D:\\code\\takeout");
		context.setValue(ENTITY_NAME, "CustomerPayStatus");
//		context.setValue(SERVICE_PATH, "D:\\code\\takeout\\shop\\src\\main\\java\\com\\ybkj\\takeout\\shop\\service");
		context.setValue(SERVICE_PATH, "D:\\code\\takeout\\client\\src\\main\\java\\com\\ybkj\\takeout\\client\\service");
		serviceGenerator.generate(context);
	}

	@Override
	public void generate(GeneratorContext context) {
		String projectPath = context.getValue(PROJECT_PATH);
		String entityName = context.getValue(ENTITY_NAME);
		String servicePath = context.getValue(SERVICE_PATH);
		String entityPackage = findClassPackage(projectPath, entityName);
		String mapperPackage = findClassPackage(projectPath, entityName + "Mapper");
		String interface_service_package = mavenDefaultGetPackage(servicePath, projectPath);

		writeServiceFile(entityName, servicePath, entityPackage, interface_service_package);
		writeServiceImplFile(entityName, servicePath, entityPackage, interface_service_package, mapperPackage);
	}

	private void writeServiceImplFile(String entityName, String servicePath, String entityPackage, String interface_service_package, String mapperPackage) {
		File serviceJavaFile = new File(servicePath + File.separator + "impl" + File.separator + entityName + "ServiceImpl.java");
		PrintWriter pw = null;
		try {
			if (serviceJavaFile.createNewFile()) {
				pw = new PrintWriter(new OutputStreamWriter(new FileOutputStream(serviceJavaFile), "UTF-8"));
				pw.println("package " + interface_service_package + ".impl;");
				pw.println();
				pw.println("import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;");
				pw.println("import org.springframework.stereotype.Service;");
				pw.println("import " + entityPackage + "." + entityName + ";");
				pw.println("import " + interface_service_package + "." + entityName + "Service;");
				pw.println("import " + mapperPackage + "." + entityName + "Mapper;");
				pw.println();
				pw.println("@Service");
				pw.println("public class " + entityName + "ServiceImpl extends ServiceImpl<" + entityName + "Mapper, " + entityName +"> implements "+ entityName +
					"Service"
					+ "{");


				pw.println();
				pw.println("}");
				pw.flush();
				System.out.println("ServiceImpl文件已生成");
			}
		} catch (IOException e) {
			e.printStackTrace();
		}finally {
			if(null != pw) {
				pw.close();
			}
		}
	}


	private void writeServiceFile(String entityName, String servicePath, String entityPackage, String interface_service_package) {
		File serviceJavaFile = new File(servicePath + File.separator + entityName + "Service.java");
		PrintWriter pw = null;
		try {
			if (serviceJavaFile.createNewFile()) {
				pw = new PrintWriter(new OutputStreamWriter(new FileOutputStream(serviceJavaFile), "UTF-8"));
				pw.println("package " + interface_service_package + ";");
				pw.println();
				pw.println("import com.baomidou.mybatisplus.extension.service.IService;");
				pw.println("import " + entityPackage + "." + entityName + ";");
				pw.println();
				pw.println("public interface " + entityName + "Service extends IService<" + entityName +"> {");
				pw.println();
				pw.println("}");
				pw.flush();
				System.out.println("Service文件已生成");
			}
		} catch (IOException e) {
			e.printStackTrace();
		}finally {
			if(null != pw) {
				pw.close();
			}
		}
	}

	private String mavenDefaultGetPackage(String servicePath, String projectPath) {
		File nearestPom = searchFileUponFile("pom.xml", new File(servicePath));
		String pomAbsolutePath = nearestPom.getAbsolutePath();
		String substring = pomAbsolutePath.substring(0, pomAbsolutePath.length() - "pom.xml".length());
		String srcBasePath = substring + "src\\main\\java";
		String endPath = servicePath.substring(servicePath.indexOf(srcBasePath) + srcBasePath.length() + 1);
		String interface_service_package = endPath.replaceAll("\\\\", ".");
		return interface_service_package;
	}

	private String findClassPackage(String projectPath, String className) {
		String targetName = className + ".java";
		File file = new File(projectPath);
		if (file.exists() && file.isDirectory()) {
			File target = searchFileInFile(targetName, file);
			if (null == target) {
				throw new IllegalArgumentException("实体类[" + targetName + "]没有找到");
			}
			try {
				FileInputStream fileInputStream = new FileInputStream(target);
				BufferedReader bf = new BufferedReader(new InputStreamReader(fileInputStream, "UTF-8"));
				String packageSentenses = bf.readLine();
				String pakeageKeyWorld = "package ";
				int start = packageSentenses.indexOf(pakeageKeyWorld) + pakeageKeyWorld.length();
				int end = packageSentenses.indexOf(";");
				String substring = packageSentenses.substring(start, end);
				return substring;
			} catch (FileNotFoundException e) {
				e.printStackTrace();
			} catch (UnsupportedEncodingException e) {
				e.printStackTrace();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		return null;
	}

	/**
	 * 在文件上层搜索指定文件
	 *
	 * @param targetName
	 * @param file
	 * @return
	 */
	public File searchFileUponFile(String targetName, File file) {
		File parentFile = file.getParentFile();
		File[] children = parentFile.listFiles();
		for (File child : children) {
			if (child.getName().equals(targetName)) {
				return child;
			}
		}
		return searchFileUponFile(targetName, parentFile);
	}

	/**
	 * 根据文件中搜索子文件
	 *
	 * @param targetName
	 * @param file
	 * @return
	 */
	public File searchFileInFile(String targetName, File file) {
		if (!file.isDirectory()) {
			if (file.getName().equals(targetName)) {
				return file;
			}
			return null;
		} else {
			File[] children = file.listFiles();
			for (File child : children) {
				File resultFile = searchFileInFile(targetName, child);
				if (null != resultFile) {
					return resultFile;
				}
			}
			return null;
		}
	}

	@Override
	public String getName() {
		return null;
	}

	@Override
	public List<TerminalModel> getModels() {
		List<TerminalModel> terminalModels = new ArrayList<>();
		put(terminalModels, "项目地址", "projectPath");
		put(terminalModels, "service地址", "servicePath");
		put(terminalModels, "实体类名", "entityName");
		return terminalModels;
	}

	@Override
	public void start() {

	}
}
